package com.yet.container.loader;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;

import com.yet.container.Container;
import com.yet.container.registry.RegistryMeta.Address;
import com.yet.container.registry.RegistryMeta.ServiceMeta;
import com.yet.listener.RegistryEvent;
import com.yet.rule.Rule;

/**
 * 多注册中心实现
 */
public class MultiServiceLoader extends ServicesLoader implements Container, ApplicationListener<ApplicationEvent> {

	private static final Logger logger = LoggerFactory.getLogger(MultiServiceLoader.class);

	private final Map<String, ConsumerServiceLoader> consumerServiceLoaders;

	private volatile State state = new State("远程服务抓取容器", true);

	public MultiServiceLoader(Map<String, ConsumerServiceLoader> consumerServiceLoaders) {
		this.consumerServiceLoaders = consumerServiceLoaders.values().stream()
				.collect(Collectors.toMap(rc -> rc.getName(), rc -> rc));
	}

	@Override
	public void start() {
		state.setInfo("多注册中心服务抓取器："
				+ consumerServiceLoaders.values().stream().map(c -> c.getName()).collect(Collectors.toList()));
	}

	@Override
	public void stop() {
		consumerServiceLoaders.values().forEach(c -> c.destroy());
		state.setStarted(false);
	}

	@Override
	public void fetchSocketAddress() {
		consumerServiceLoaders.values().forEach(c -> c.fetchSocketAddress());
	}

	private ConsumerServiceLoader getConsumerServiceLoader(String name) {
		if (StringUtils.isNotBlank(name)) {
			return consumerServiceLoaders.get(name);
		}
		if (consumerServiceLoaders.size() == 1) {
			return consumerServiceLoaders.values().iterator().next();
		}
		throw new IllegalArgumentException("存在多个服务加载器(多个注册中心),请选择其中一个");
	}

	@Override
	public String getName() {
		return "multiServiceLoader";
	}

	@Override
	public int getOrder() {
		return Ordered.HIGHEST_PRECEDENCE;
	}

	@Override
	public State getState() {
		return state;
	}

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof RegistryEvent) {
			RegistryEvent registryEvent = (RegistryEvent) event;
			onRegistryEvent(registryEvent);
		} else if (event instanceof ContextRefreshedEvent) {
			consumerServiceLoaders.values().forEach(c -> c.init());
		}
	}

	@Override
	public void onRegistryEvent(RegistryEvent registryEvent) {
		logger.info("事件:[{}]", registryEvent);
		getConsumerServiceLoader(registryEvent.getName()).onRegistryEvent(registryEvent);
	}

	@Override
	public List<Address> lookupAddresses(ServiceMeta meta) {
		return getConsumerServiceLoader(meta.getRegistryCenterName()).lookupAddresses(meta);
	}

	@Override
	public Rule getRule(String args) {
		return getConsumerServiceLoader(args).getRule(null);
	}

}
